#include "laser.h"

uint8_t rxdata;
uint8_t rx_buff[128];
uint8_t step = 0;

float laser_in_v;
float laser_dis;

/**
 * @brief  获取校验位
 * @param  
 * @retval 无
 */
uint8_t get_ack(uint8_t *buff, uint8_t len)
{
	uint8_t ack = 0;
	
	for (uint8_t i=0; i < len; i++) {
		ack += buff[i];
	}
	
	return ack;
}

/**
 * @brief  发送命令
 * @param  
 * @retval 无
 */
void laser_tx_cmd(uint16_t tx_cmd)
{
	uint8_t tx_buff[] = {
		0xAA,
		0x80,
		tx_cmd>>8,
		tx_cmd&0xff,
		0x00/* ack */
	};
	
	uint8_t len = sizeof(tx_buff);
	
	tx_buff[len-1] = get_ack(&tx_buff[1], len-2);
	
	HAL_UART_Transmit(&huart1, tx_buff, len, 0xff);
}

/**
 * @brief  写命令
 * @param  
 * @retval 无
 */
void laser_write_data(uint16_t tx_cmd, uint16_t data)
{
	uint8_t tx_buff[] = {
		0xAA,
		0x00,
		tx_cmd>>8,
		tx_cmd&0xff,
		1>>8,
		1&0xff,
		data>>8,
		data&0xff,
		0x00/* ack */
	};
	
	uint8_t len = sizeof(tx_buff);
	
	tx_buff[len-1] = get_ack(&tx_buff[1], len-2);
	
	HAL_UART_Transmit(&huart1, tx_buff, len, 0xff);
}

/**
 * @brief  处理数据
 * @param  
 * @retval 无
 */
void laser_dispose(uint8_t *data)
{
	uint16_t reg     = data[1]<<8 | data[2];
	uint16_t ok_math = data[3]<<8 | data[4];
	uint16_t ok_data = data[5]<<8 | data[6];
	
	switch(reg)
	{
		case la_voltage:
			laser_in_v = HEX_TO_DECIMAL(ok_data) / 1000.f;
		break;
		case 0x0022:	//读取测量值
			laser_dis = data[5]<<24 | data[6]<<16 | data[7]<<8 | data[8];
		break;
	}
}

uint16_t num;
uint16_t cnt;

/**
 * @brief  激光接收
 * @param  
 * @retval 无
 */
void laser_rx_for_uart(uint8_t data)
{
	switch(step)
	{
		// 检测帧头
		case 0:{
			rx_buff[0] = data;
			
			if (data == 0xAA) {
				step = 1;
			}
			break;
		}
		
		// 地址
		case 1:{
			rx_buff[1] = data;
			step = 2;
			break;
		}
		
		// 寄存器1
		case 2:{
			rx_buff[2] = data;
			step = 3;
			break;
		}
		// 寄存器2
		case 3:{
			rx_buff[3] = data;
			step = 4;
			break;
		}
		
		
		// 有效计算1
		case 4:{
			rx_buff[4] = data;
			step = 5;
			break;
		}
		// 有效计算2
		case 5:{
			rx_buff[5] = data;
			step = 6;
			num = data * 2;
			cnt = 0;
			break;
		}
		
		
		// 有效字节
		case 6:{
			rx_buff[6+cnt] = data;
			cnt++;
			
			if (--num == 0) {
				step = 8;
			}
			break;
		}
		
		// 校验位
		case 8:{
			if (get_ack(&rx_buff[1], 5 + cnt) == data) {
				laser_dispose(&rx_buff[1]);
			}
			
			step = 0;
			break;
		}
		
		// 结束
		case 0xff:{
			
			step = 0;
			break;
		}
	}
}

/**
 * @brief  中断函数
 * @param  
 * @retval 无
 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == huart1.Instance) {
		laser_rx_for_uart(rxdata);
		HAL_UART_Receive_IT(&huart1, &rxdata, 1);
	}
}

/**
 * @brief  初始化
 * @param  
 * @retval 无
 */
void laser_init(void)
{
	laser_write_data(set_led, 01);
	HAL_Delay(100);
	laser_write_data(set_led, 01);
	HAL_Delay(100);
	
	laser_write_data(set_offset, 25);
	HAL_Delay(100);
	laser_write_data(set_offset, 25);
	HAL_Delay(100);
	
	HAL_UART_Receive_IT(&huart1, &rxdata, 1);
}

/******************* (C) COPYRIGHT 2025 FUYEBING*****END OF FILE************/
